#pragma once
#include "util/noncopyable.h"
#include "base/function.h"
#include "base/config.h"

#include <vector>
#include <memory.h>
namespace net_tools
{
  class Eventloop;
  namespace base
  {
    class Timeevery;
  } // namespace base
  namespace net
  {
    class Connect;
    namespace detail
    {
      struct min_heartbeat_struct
      {
        min_heartbeat_struct()
            : IS_ALIVE(0),
              SIZE(0){};
        uint64_t IS_ALIVE;
        uint8_t SIZE;
        net_tools::net::Connect *connect_vector[64];
      };
      class heartbeat_struct
      {
      public:
        heartbeat_struct()
            : free_min_heartbeat_vector_(),
              all_min_heartbeat_vector_()
        {
          No_Free_min_heartbeat_();
        };
        void No_Free_min_heartbeat_()
        {
          min_heartbeat_struct *new_ = new min_heartbeat_struct();
          free_min_heartbeat_vector_.push_back(new_);
          all_min_heartbeat_vector_.push_back(new_);
        };
        void Add_free_min_heartbeat_(min_heartbeat_struct *min_heartbeat_)
        {
          free_min_heartbeat_vector_.push_back(min_heartbeat_);
        };
        std::vector<min_heartbeat_struct *> free_min_heartbeat_vector_;
        std::vector<min_heartbeat_struct *> all_min_heartbeat_vector_;
      };
    } // namespace detail
    class Heartbeat : net_tools::util::noncopyable
    {
    public:
      Heartbeat(net_tools::Eventloop *eventloop, connect_func heartbeat_lose_func);
      ~Heartbeat(){};
      void Start();
      void Stop();
      void Timeout();
      void Add_heartbeat(Connect *connect);
      //only call by connect Heartbeat_Close_connect_todo
      void Del_heartbeat(Connect *connect);
      void Lose_heartbeat(Connect *connect);
      uint64_t index_vector_[65];

    private:
      void Now_full_add(Connect *connect);
      net_tools::Eventloop *eventloop_;
      connect_func heartbeat_lose_func_;
      detail::heartbeat_struct *heart_struct_[_C::HEARTBEAT_VECTOR_SIZE];
      //now time
      uint32_t time_index_;
      //last one
      uint32_t free_time_index_;
      net_tools::base::Timeevery *timeevery_;
    };
#define INDEX_VECTOR        \
  {                         \
    0x0000000000000001,     \
        0x0000000000000002, \
        0x0000000000000004, \
        0x0000000000000008, \
        0x0000000000000010, \
        0x0000000000000020, \
        0x0000000000000040, \
        0x0000000000000080, \
        0x0000000000000100, \
        0x0000000000000200, \
        0x0000000000000400, \
        0x0000000000000800, \
        0x0000000000001000, \
        0x0000000000002000, \
        0x0000000000004000, \
        0x0000000000008000, \
        0x0000000000010000, \
        0x0000000000020000, \
        0x0000000000040000, \
        0x0000000000080000, \
        0x0000000000100000, \
        0x0000000000200000, \
        0x0000000000400000, \
        0x0000000000800000, \
        0x0000000001000000, \
        0x0000000002000000, \
        0x0000000004000000, \
        0x0000000008000000, \
        0x0000000010000000, \
        0x0000000020000000, \
        0x0000000040000000, \
        0x0000000080000000, \
        0x0000000100000000, \
        0x0000000200000000, \
        0x0000000400000000, \
        0x0000000800000000, \
        0x0000001000000000, \
        0x0000002000000000, \
        0x0000004000000000, \
        0x0000008000000000, \
        0x0000010000000000, \
        0x0000020000000000, \
        0x0000040000000000, \
        0x0000080000000000, \
        0x0000100000000000, \
        0x0000200000000000, \
        0x0000400000000000, \
        0x0000800000000000, \
        0x0001000000000000, \
        0x0002000000000000, \
        0x0004000000000000, \
        0x0008000000000000, \
        0x0010000000000000, \
        0x0020000000000000, \
        0x0040000000000000, \
        0x0080000000000000, \
        0x0100000000000000, \
        0x0200000000000000, \
        0x0400000000000000, \
        0x0800000000000000, \
        0x1000000000000000, \
        0x2000000000000000, \
        0x4000000000000000, \
        0x8000000000000000, \
        0x0000000000000000, \
  }
  } // namespace net
} // namespace net_tools